package day02.nio02;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Set;

/**
 * NIO下网络编程 - 客户端 - 少量线程处理大量客户端
 */
public class SCDemo02 {
    public static void main(String[] args) throws Exception {
        System.out.println("客户端启动");
        //1.创建sc
        SocketChannel sc = SocketChannel.open();
        //2.开启非阻塞模式
        sc.configureBlocking(false);
        //3.发起连接
        sc.connect(new InetSocketAddress("localhost", 9999));
        //4.创建选择器
        Selector selector = Selector.open();
        //5.注册连接操作
        sc.register(selector, SelectionKey.OP_CONNECT);
        while(true){
            //--进行选择操作
            selector.select();
            //--获取就绪的键
            Set<SelectionKey> set = selector.selectedKeys();
            //--遍历处理就绪的键
            Iterator<SelectionKey> it = set.iterator();
            while(it.hasNext()){
                //--得到就绪的键
                SelectionKey sk = it.next();
                //--获取就绪的键的操作类型
                if(sk.isAcceptable()){

                }else if(sk.isConnectable()){
                    //--获取通道
                    SocketChannel selc_sc = (SocketChannel) sk.channel();
                    //--连接服务器
                      //--完成连接
                    while(!selc_sc.finishConnect()){}
                    //--注册写操作
                    selc_sc.register(selector, SelectionKey.OP_WRITE);
                }else if(sk.isReadable()){
                    //--获取通道
                    SocketChannel selc_sc = (SocketChannel) sk.channel();
                    //--读取数据
                    ByteBuffer buf = ByteBuffer.allocate(13);
                    while(buf.hasRemaining()){
                        selc_sc.read(buf);
                    }
                    buf.flip();
                    byte[] data = buf.array();
                    String str = new String(data, StandardCharsets.UTF_8);
                    System.out.println(str);
                    //--注册写操作
                    selc_sc.register(selector, SelectionKey.OP_WRITE);
                }else if(sk.isWritable()){
                    //--获取通道
                    SocketChannel selc_sc = (SocketChannel) sk.channel();
                    //--写数据
                    ByteBuffer buf = ByteBuffer.wrap("hello nio!".getBytes());
                    while(buf.hasRemaining()){
                        selc_sc.write(buf);
                    }
                    //--注册读操作，读取服务器返回的数据
                    selc_sc.register(selector, SelectionKey.OP_READ);
                }else{

                }
                //8.删除已经处理的键
                it.remove();
            }
        }

    }
}
